package com.rcy.server.controller;


import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonParser;
import com.rcy.server.pojo.MyFile;
import com.rcy.server.service.FileService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.json.GsonJsonParser;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;



import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * 处理客户请求的controller
 * @author RuicyWu
 * @Date 2021/11/5 21:54
 */
@RestController
public class FileServer {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private FileService fileService;

    /**
     * 实现文件上传功能
     * 并把文件的元数据存储到数据库中
     * 把新的文件名返回给客户端
     * @param ofilename 旧的文件名
     * @param filetype 文件类型
     * @param request  用于获取数据流
     * @param response  用于将新的文件名写回给客户端
     */
    @PostMapping(value = "/upload/{ofilename}/{filetype}",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public void uploadFile(@PathVariable("ofilename") String ofilename, @PathVariable("filetype") String filetype, HttpServletRequest request, HttpServletResponse response)
    {
        logger.info("文件上传业务开始");
        InputStream is = null;
        ServletOutputStream sos=null;
        Date date=new Date();
        byte[] bytes=new byte[2048];
        DateFormat df=new SimpleDateFormat("yyyyMMdd");
        //生成目录路径名
        String filepath=df.format(date);
        //生成新文件名
        String nfilename=UUID.randomUUID().toString().trim().replaceAll("-","");
        MyFile myFile = new MyFile();
        myFile.setFileName(nfilename);
        myFile.setFileOriginalname(ofilename);
        myFile.setFileType(filetype);
        File dir=new File("D:\\"+filepath);
        if(!dir.exists())
        {
            dir.mkdirs();
        }
        File file=new File(dir,nfilename+"."+filetype);
        myFile.setFileCreatetime(new Date());
        myFile.setFilePath(dir.getAbsolutePath());
        FileOutputStream fos=null;
        try {

            fos=new FileOutputStream(file,true);
            is=request.getInputStream();

            int len=0;
            while ((len=is.read(bytes))!=-1)
            {
                fos.write(bytes,0,len);
            }
            myFile.setFileSize(file.length()+"");
            sos=response.getOutputStream();
            sos.write(nfilename.getBytes("UTF-8"));
            fileService.add(myFile);
            logger.info("文件上传业务结束");
        }catch (Exception e)
        {
             e.printStackTrace();
        }finally {
            if(null!=sos)
            {
                try {
                    sos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(null!=is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(null!=fos){
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            }
            file=null;
            dir=null;
             bytes=null;
        }

    }

    /**
     * 文件下载
     * @param uuid 文件名，即uuid
     * @param response 用于将文件数据写回客户端
     */
    @GetMapping(value = "/down/{uuid}")
    public void downFile(@PathVariable("uuid") String uuid,HttpServletResponse response)
    {
        logger.info("文件下载业务开始");
        File file=null;
        OutputStream os=null;
        FileInputStream fis=null;
        BufferedInputStream bis=null;
        BufferedOutputStream bos=null;
        byte[] bytes=new byte[2048];
        try {
            //调用服务层的方法
            MyFile fileMetaData = fileService.getFileMetaDataByFileName(uuid);
           file=new File(fileMetaData.getFilePath()+"\\"+fileMetaData.getFileName()+"."+fileMetaData.getFileType());
           fis=new FileInputStream(file);
           bis=new BufferedInputStream(fis);
           os=response.getOutputStream();
           bos=new BufferedOutputStream(os);
           int len=0;
           while ((len=bis.read(bytes))!=-1)
           {
               bos.write(bytes,0,len);
           }
           bos.flush();
           logger.info("文件下载业务结束");
        }catch (Exception e)
        {
            e.printStackTrace();
            response.setStatus(410);
        }finally {
            //关闭与释放资源
            if(bos!=null)
            {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(os!=null)
            {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(bis!=null)
            {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(fis!=null)
            {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            bytes=null;
            file=null;
        }
    }

    /**
     * 获取文件元数据
     * @param uuid    文件名
     * @param response 用于写回结果的响应对象
     */
    @GetMapping("/getmetadata/{uuid}")
    public void getMetaData(@PathVariable("uuid") String uuid,HttpServletResponse response)
    {
        OutputStream os=null;
        try {
            os=response.getOutputStream();
            //调用服务层的方法查询
           MyFile myFile=fileService.getFileMetaDataByFileName(uuid);
           //调用alibaba的json工具将对象转换为json字符串
            String resultJson= JSON.toJSONString(myFile);
            os.write(resultJson.getBytes("UTF-8"));
        }
        catch (Exception e)
        {
         e.printStackTrace();
        }finally {
            //关闭流对象
            if(os!=null)
            {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
